package com.shoulder.mybatis.utils;

import com.shoulder.core.api.ApiUser;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
 * Copyright (c) 2024-2050 heguangchuan <596767880@qq.com>
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * <a href="http://www.apache.org/licenses/LICENSE-2.0">...</a>
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * <p>
 * 哎 太难了 没想到只是写着玩玩  却耐着性子一直写下来了
 *
 * @author 596767880@qq.com
 * @since 2024/5/10 下午4:48
 * 构建sql
 */
public class ScopeUtils {
    /**
     * @param alias      表的别名
     * @param properties 属性
     * @param apiUser    当前用户
     * @return Expression
     */
    public static Expression enhanceExpression(String alias, String properties, ApiUser apiUser) throws JSQLParserException {
        if (apiUser == null) {
            return null;
        }
        if ("user_id".equals(properties)) {
            //处理用户的逻辑
            return buildUserExpression(alias, apiUser.getId());
        }
        if ("dept_id".equals(properties)) {
            //处理部门的逻辑
            return buildDeptExpression(alias, apiUser.getDataScopes());
        }
        if ("tenant_id".equalsIgnoreCase(properties)) {
            return buildTenantExpression(alias, apiUser.getTenantId());
        }
        return null;
    }

    public static Expression buildTenantExpression(String alias, String tenantId) throws JSQLParserException {
        return CCJSqlParserUtil.parseCondExpression(buildTenantSQL(alias, tenantId));
    }

    private static Expression buildDeptExpression(String alias, List<String> dataScopes) throws JSQLParserException {

        return CCJSqlParserUtil.parseCondExpression(buildDeptSQL(alias, dataScopes));
    }

    private static Expression buildUserExpression(String alias, String userId) throws JSQLParserException {
        String sql = buildUserSQL(alias, userId);
        return CCJSqlParserUtil.parseCondExpression(sql);
    }

//    public static Expression combineExpression(Expression where, Expression expression, String column) {
//        if ("dept_id".equals(column)) {
//            return new InExpression(where, expression);
//        }
//        return new AndExpression(where, expression);
//    }

    public static String buildSQL(String column, String alias, ApiUser apiUser) {
        if ("dept_id".equals(column)) {
            return buildDeptSQL(alias, apiUser.getDataScopes());
        }
        if ("tenant_id".equalsIgnoreCase(column)) {
            return buildTenantSQL(alias, apiUser == null ? "" : apiUser.getTenantId());
        }
        return buildUserSQL(alias, apiUser.getId());
    }

    public static String buildDeptSQL(String alias, List<String> dataScopes) {
        if (CollectionUtils.isEmpty(dataScopes)) {
            return null;
        }
        String inSQL = String.join(",", dataScopes.stream().map(each -> "'" + each + "'").toList());
        String sql = "dept_id in (" + inSQL + ")";
        if (alias != null && !alias.isEmpty()) {
            sql = alias + ".dept_id in (" + inSQL + ")";
        }
        return sql;
    }

    private static String buildTenantSQL(String alias, String tenantId) {
        if (ObjectUtils.isEmpty(tenantId)) {
            return null;
        }
        String sql = "tenant_id='" + tenantId + "'";
        if (alias != null && !alias.isEmpty()) {
            sql = alias + ".tenant_id='" + tenantId + "'";
        }
        return sql;
    }

    public static String buildUserSQL(String alias, String userId) {
        String sql = "user_id='" + userId + "'";
        if (alias != null && !alias.isEmpty()) {
            sql = alias + ".user_id='" + userId + "'";
        }
        return sql;
    }
}
